package com.zkh.myframe.database.mapper.parser;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import com.zkh.myframe.database.mapper.MapperParseException;
import com.zkh.myutils.utils.Regexp;
import com.zkh.myutils.utils.StringUtils;

/**
 * 解析相关工具类
 * @author zkh
 */
public class ParseUtils {
	
	/**
	 * 获取枚举类值
	 * @param className 枚举类名称（含包名）
	 * @param enumName 枚举值
	 * @param methodOrField 枚举值属性或方法。如果该项为空，则返回枚举类，如果以括号结尾，则判断为方法
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getEnumValue(String className, String enumName, String methodOrField, Class<T> cls){
		try {
			//有空值
			if(StringUtils.isExistEmpty(className, enumName)) {
				throw new MapperParseException("枚举类初始化失败");
			}
			//去掉空格
			if(methodOrField!=null) {
				methodOrField = methodOrField.trim();
			}
			//方法或属性为空
			boolean isEmpty = StringUtils.isEmpty(methodOrField);
			//方法或属性为空格式
			if(!isEmpty && !Regexp.isMatch("^[a-zA-Z_]+(\\(\\))?", methodOrField)) {
				throw new MapperParseException("枚举值属性或方法格式错误");
			}
			//初始化枚举类
			Object obj = Class.forName(className).getField(enumName).get(null);
			//属性和方法为空
			if(isEmpty) {
				return (T) obj;
			}
			if(methodOrField.endsWith("()")) {
				return (T) obj.getClass().getMethod(methodOrField.substring(0, methodOrField.length()-2)).invoke(obj);
			}
			return (T) obj.getClass().getField(methodOrField).get(obj);
		} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException
				| ClassNotFoundException | InvocationTargetException | NoSuchMethodException e) {
			throw new MapperParseException("枚举类初始化失败", e);
		}
	}
	
	/**
	 * 获取静态属性值（public）
	 * @param classInfos 类信息，长度至少为2
	 */
	public static Object getFieldValue(String[] classInfos) {
		if(classInfos==null || classInfos.length<2) {
			throw new MapperParseException("静态属性值获取失败");
		}
		return getFieldValue(classInfos[0], classInfos[1]);
	}
	
	/**
	 * 获取静态属性值（public）
	 * @param className 类名，包含包名
	 * @param variableName 变量名。必须是静态变量。
	 */
	public static Object getFieldValue(String className, String variableName) {
		try {
			return Class.forName(className).getField(variableName).get(null);
		} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException
				| ClassNotFoundException e) {
			throw new MapperParseException("属性值获取失败", e);
		}
	}
	
	/**
	 * 检查是否是常量，即 final static修饰的变量
	 * @param className 类名，包含包名
	 * @param variableName 变量名。必须是静态变量。
	 * @return 是常量，返回true，其它（包含异常）均返回false。
	 */
	public static boolean isFinalVariable(String className, String variableName) {
		try {
			return Class.forName(className).getField(variableName).getModifiers()==Modifier.PUBLIC + Modifier.FINAL + Modifier.STATIC;
		} catch (NoSuchFieldException | SecurityException | ClassNotFoundException e) {
			return false;
		}
	}
}
